﻿// -----------------------------------------------------------------------
// This class implements the Application class in the specification.
// An enum was used for the ApplicationStatus free type.
//
// Author: Dan Buvid
// Date: April 13, 2012
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace ResidencyPlacement
{
    public enum ApplicationStatus { Applied, Interviewed, HasBeenSelected, OfferAccepted, Declined };

    public class Application
    {
        // The state space consists of 
        // a hospital
        // an application status
        // a cumulative mark for the entrance exam and interview
        private int hospital;
        private ApplicationStatus status;
        private int cumulativeMark;

        /// <summary>
        /// This is the constructor method that implements the 'Init' state.
        /// </summary>
        public Application()
        {
            // The state invariant must be checked before the operation.
            if (!stateInvariantCheck())
                Console.WriteLine("\n Init state implemented by the constructor failed because "
                                  + "the state invariant is violated \n");

            status = ApplicationStatus.Applied;
            cumulativeMark = 0;
        }

        /// <summary>
        /// This method implements the state invariant check.
        /// </summary>
        /// <returns>boolean result indicating whether or not state invariant is satisfied.</returns>
        private bool stateInvariantCheck()
        {
            bool result = true;

            if (status != ApplicationStatus.Applied)
            {
                result = cumulativeMark >= 0;
            }

            return result;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string p)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(p));
            }
        }

        public int Hospital
        {
            get
            {
                return this.hospital;
            }
            set
            {
                hospital = value;
                NotifyPropertyChanged("Hospital");
            }
        }

        public ApplicationStatus Status
        {
            get
            {
                return this.status;
            }
            set
            {
                status = value;
                NotifyPropertyChanged("Status");
            }
        }

        public int CumulativeMark
        {
            get
            {
                return this.cumulativeMark;
            }
            set
            {
                cumulativeMark = value;
                NotifyPropertyChanged("CumulativeMark");
            }
        }
    }
}
